import time
from rest_framework import serializers
from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler
from . import models
from course.models import Course
from libs.iPay import alipay, alipay_gateway
from django.conf import settings

"""
@author RansySun
@create 2019-12-02-19:04
"""


class OrderModelSerializer(serializers.ModelSerializer):
    # 购买课程的主键们：暂定 '1,2,3' 方式传多个主键
    goods_pks = serializers.CharField(max_length=64)

    class Meta:
        model = models.Order
        fields = (
            "subject",  # 订单标题
            "total_amount",  # 订单总价
            "pay_type",  # 支付方式
            "pay_type",
            "goods_pks",
        )
        extra_kwargs = {
            "total_amount": {
                "required": True
            }
        }

    # 后台要根据所有的主键和总价，校验价格（防止传输中被修改）

    def validate(self, attrs):

        # 移除自定义的字段，用于购买多个商品的id
        goods_pks = attrs.pop("goods_pks")
        goods_pks = [pk for pk in goods_pks.split(",")]
        goods_obj = []

        # 判断课程是否已经存在
        for pk in goods_pks:
            try:
                course_obj = Course.objects.get(pk=pk)
                goods_obj.append(course_obj)

            except:
                raise serializers.ValidationError({"pk": "课程主键有误"})

        # 计算课程的总价格
        total_price = 0

        for good in goods_obj:
            total_price += good.price

        # 商品价格是否一致
        total_amount = attrs.get("total_amount")
        if total_price != total_amount:
            raise serializers.ValidationError({"total_amount": "价格有误"})

        # 生成订单号
        order_on = self._get_order_on()

        # 订单名称
        subject = attrs.get("subject")
        total_amount = float(total_amount)
        if total_amount <= 0:
            raise serializers.ValidationError({"total_amount": "金额不能不能为零"})
        if total_amount > 0:
            # 生成订单链接
            order_params = alipay.api_alipay_trade_page_pay(
                subject=subject,  # 订单名称
                total_amount=total_amount,  # 订单价格
                out_trade_no=order_on,  # 订单编号
                return_url=settings.RETURN_URL,  # 前台回调接口
                notify_url=settings.NOTIFY_URL,  # 支付宝一步回调接口
                # return_url="http://localhost:8080",  # 同步回调的前台接口
                # notify_url="https://example.com/notify"  # 异步回调的后台接口
            )

            # 拼接订单连接
            pay_url = alipay_gateway + order_params

            # 将支付宝链接保存到serializer对象中
            self.pay_url = pay_url

        # 添加订单比好字段保存至数据库中
        attrs['out_trade_no'] = order_on

        # 视图类给序列化类传参
        attrs['user'] = self.context.get("request").user

        # 将所有的商品对象存放在校验数据中，辅助订单详情表商品信息的入库
        attrs['courses'] = goods_obj

        return attrs

    # 重写create方法,完成订单详情入口操作

    def create(self, validated_data):

        # 用于添加订单详情表
        courses = validated_data.pop("courses")

        # 创建订单表
        order = super().create(validated_data)

        # 关系表操作
        order_detail_list = []
        for course in courses:
            order_detail_list.append(
                models.OrderDetail(order=order, course=course, price=course.price, real_price=course.price)

            )

        # 将多个订单详情对象，批量入库，放入到订单的详情表中
        models.OrderDetail.objects.bulk_create(order_detail_list)
        return order

    def _get_order_on(self):
        """
        生成订单编号
        :return:
        """
        order = time.time()
        return str(order).replace('.', "", 1)
